/*
 * Author:   W.SH
 */
package com.wgg.crawler.scheduler.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 〈一句话功能简述〉<br> 
 * 〈功能详细描述〉
 *
 *  @author W.SH
 */
public class ThreadPool {

    private final int DEFAULT_POOL_SIZE = 8;
    
    private final int MAX_POOL_SIZE = 64;
    
    private volatile int poolSize = DEFAULT_POOL_SIZE;
    
    private AtomicInteger activceThread = new AtomicInteger();
    
    private ExecutorService executorService;
    
    private ReentrantLock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    
    public ThreadPool(int poolSize, ExecutorService executorService) {
        if (poolSize >= DEFAULT_POOL_SIZE && poolSize <= MAX_POOL_SIZE) {
            this.poolSize = poolSize;
        }
        this.executorService = executorService;
    }
    
    public ThreadPool(int poolSize) {
        if (poolSize >= DEFAULT_POOL_SIZE && poolSize <= MAX_POOL_SIZE) {
            this.poolSize = poolSize;
        }
        executorService = Executors.newFixedThreadPool(this.poolSize);
    }
    
    
    public void execute(final Runnable runnable){
        lock.lock();
        try {
            while (activceThread.get() >= poolSize){
                condition.await();
            }
        } catch (InterruptedException e) {
        }finally {
            lock.unlock();
        }
        activceThread.incrementAndGet();
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    runnable.run();
                } finally {
                    lock.lock();
                    try {
                        condition.signalAll();
                        activceThread.decrementAndGet();
                    } finally {
                        lock.unlock();
                    }
                }
            }
        });
    }

    public ExecutorService getExecutorService() {
        return executorService;
    }
    
    public AtomicInteger getActivceThread() {
        return activceThread;
    }
    
    public void close() {
        System.out.println("threadpool closing");
        executorService.shutdown();
    }
    
}
